#include <unistd.h>
#include <pwd.h>
#include <grp.h>

#include <QStringList>
#include <QMutex>
#include <QDateTime>
#include <QDir>
#include <QFile>
#include <QTextStream>
#include <QThread>
#include <QDebug>
#include <QProcess>
#include <QByteArray>

#include "common.h"

CheckRes checkCommand(const QStringList &command)
{
    if (command.isEmpty())
        return MAINWINDOW;
    else if(command.at(0).compare("debug")==0)
        return DEBUG;
    else if(command.at(0).compare("show")==0)
        return MAINWINDOW;
    else if (command.size() != 2) {
        return CHECK_FALSE;
    }
    else if (command.at(0).compare("add")==0
          || command.at(0).compare("remove")==0
          || command.at(0).compare("add_uri")==0 ) {
            
        return POPWINDOW;
    }
    return CHECK_FALSE;
}


/**
 * qDebug 重定向：
 * 打印代码位置及调用函数，以及所在线程
 * 
 */
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QByteArray localMsg = msg.toLocal8Bit();
    switch (type) {
    case QtDebugMsg:
        fprintf(stdout, "[qDebug] %s:%u\t%s:\n", QString(context.file).remove(QDir::currentPath() + "/").toStdString().c_str(), context.line, context.function);
        qDebug () << "thread: " << QThread::currentThread();
        fprintf(stdout, "\t %s\n",localMsg.constData());
        break;
    default:
        break;
    }
}

// void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
// {
//     // 加锁
//     static QMutex mutex;
//     mutex.lock();

//     QByteArray localMsg = msg.toLocal8Bit();

//     QString strMsg("");
//     switch (type)
//     {
//     case QtDebugMsg:
//     default:
//         strMsg = QString("Debug:");
//         break;
//     case QtWarningMsg:
//         strMsg = QString("Warning:");
//         break;
//     case QtCriticalMsg:
//         strMsg = QString("Critical:");
//         break;
//     case QtFatalMsg:
//         strMsg = QString("Fatal:");
//         break;
//     }

//     // 设置输出信息格式
//     QString strDateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd ddd");
//     QString strMessage = QString(QString() +
//                                  "Message:%1"
//                                  // +"        File:%2\n"
//                                  // +"        Line:%3\n"
//                                  // +"        Function:%4\n"
//                                  // +"        DateTime:%5"
//                                  )
//                              .arg(localMsg.constData());
//     // .arg(context.file).arg(context.line).arg(context.function).arg(strDateTime);

//     // 输出信息至文件中（读写、追加形式）
//     QString dirPath = "/tmp/kylin-printer/log";
//     QDir dir;
//     QFile file;
//     if (dir.mkpath(dirPath)) {
//         dirPath = dirPath + "/" + strDateTime + ".txt" ;
//         file.setFileName(dirPath);
//     }

//     file.open(QIODevice::ReadWrite | QIODevice::Append);
//     QTextStream stream(&file);
//     stream << strMessage << "\r\n";
//     file.flush();
//     file.close();

//     // 解锁
//     mutex.unlock();
// }

QString getRetFromCommand(const QStringList &command)
{
    QProcess proc;
    QStringList options;
    options << "-c"<< command.join(" ");
    proc.closeWriteChannel();
    proc.start("bash", options);
    if (!proc.waitForFinished())
        return "";
    QString res = QString(proc.readAll());
    proc.close();
    if(res.right(1) == "\n")
        res.chop(1);
    return res;
}

void runCommand(const QStringList &command)
{
    QProcess proc;
    QStringList options;
    options << "-c"<< command.join(" ");
    proc.closeWriteChannel();
    proc.startDetached("bash", options);
    
    return ;
}

const char *qstringTochar(const QString &qstr)
{
    QByteArray ba = qstr.toLatin1();
    return ba.data();
}

QString getUserName()
{
    uid_t uid;
    uid_t NO_UID = -1;
    struct passwd *pw;

    errno = 0;
    uid = geteuid ();
    if (uid == -1 && errno) {
        qDebug () << "get uid error";
        return "";
    }
    pw = getpwuid (uid);
    if (!pw) {
        qDebug ("cannot find name for user ID %lu", (unsigned long int) uid);
        return "";
    }
    return QString(pw->pw_name);
}

bool isAdministratorUser()
{
    static gid_t list[100];
    int n_gp = getgroups(100,list);
    struct group *gp;
    for(int i = 0;i < n_gp; i++) {
        gp = getgrgid(list[i]);
        if (!gp) {
            continue;
        }
        if(QString(gp->gr_name) == "sudo") {
            return true;
        }
    }
    return false;
}